package com.lihaozhe.commons.date;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

/**
 * @author 李昊哲
 * @Description Date日期工具类
 * @createTime 2021/7/14 上午10:38
 */
public abstract class BaseDate {
    /**
     * 默认时区
     */
    private final static String timeZone = "Asia/Shanghai";
    /**
     * 默认时区为东8区
     */
    private final static ZoneOffset zoneOffset = ZoneOffset.of("+8");

    /**
     * 默认时间字符串模板
     */
    private final static String pattern = "yyyy-MM-dd HH:mm:ss";

    /**
     * 将日期对象格式化为字符串
     *
     * @param date Date对象
     * @return Date对象格式化后的日期字符串
     */
    public static String format(Date date) {
        return format(date, timeZone, pattern);
    }

    /**
     * 将日期对象格式化为字符串
     *
     * @param date    Date对象
     * @param pattern 日期格式化字符串模板
     * @return Date对象格式化后的日期字符串
     */
    public static String format(Date date, String pattern) {
        return format(date, timeZone, pattern);
    }

    /**
     * 日期对象格式化为字符串
     *
     * @param date     Date对象
     * @param timeZone 时区
     * @param pattern  日期格式化字符串模板
     * @return Date对象格式化后的日期字符串
     */
    public static String format(Date date, String timeZone, String pattern) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        dateFormat.setTimeZone(TimeZone.getTimeZone(timeZone));
        return dateFormat.format(date);
    }

    /**
     * 将日期字符串解析为日期对象
     *
     * @param text 日期字符串
     * @return 日期字符串解析后日期对象
     * @throws ParseException
     */
    public static Date parse(String text) throws ParseException {
        return parse(text, timeZone, pattern);
    }

    /**
     * 将日期字符串解析为日期对象
     *
     * @param text    日期字符串
     * @param pattern 日期格式化字符串模板
     * @return 日期字符串解析后日期对象
     * @throws ParseException
     */
    public static Date parse(String text, String pattern) throws ParseException {
        return parse(text, timeZone, pattern);
    }

    /**
     * 将日期字符串解析为日期对象
     *
     * @param text     日期字符串
     * @param timeZone 时区
     * @param pattern  日期格式化字符串模板
     * @return 日期字符串解析后日期对象
     * @throws ParseException
     */
    public static Date parse(String text, String timeZone, String pattern) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        dateFormat.setTimeZone(TimeZone.getTimeZone(timeZone));
        return dateFormat.parse(text);
    }

    /**
     * 时间补零占位
     *
     * @param time 时间
     * @return 补零后的字符串
     */
    public static String zeroCompensation(int time) {
        if (time < 10) {
            return "0" + time;
        }
        return String.valueOf(time);
    }

    /**
     * LocalDateTime类型的时间转为Date类型的时间
     *
     * @param dateTime LocalDateTime
     * @return Date
     */
    public static Date fromLocalDateTime(LocalDateTime dateTime) {
        return Date.from(dateTime.toInstant(zoneOffset));
    }

    /**
     * LocalDateTime类型的时间转为Date类型的时间
     *
     * @param dateTime   LocalDateTime
     * @param zoneOffset 时区
     * @return Date
     */
    public static Date fromLocalDateTime(LocalDateTime dateTime, ZoneOffset zoneOffset) {
        return Date.from(dateTime.toInstant(zoneOffset));
    }


    /**
     * Date类型的时间转为LocalDateTime类型的时间
     *
     * @param date Date
     * @return Date
     */
    public static LocalDateTime toLocalDateTime(Date date) {
        return date.toInstant().atOffset(zoneOffset).toLocalDateTime();
    }

    /**
     * Date类型的时间转为LocalDateTime类型的时间
     *
     * @param date       Date
     * @param zoneOffset 时区
     * @return Date
     */
    public static LocalDateTime toLocalDateTime(Date date, ZoneOffset zoneOffset) {
        return date.toInstant().atOffset(zoneOffset).toLocalDateTime();
    }

    public static String currentDateString() {
        return currentDateString(timeZone, pattern);
    }

    public static String currentDateString(String timeZone) {
        return currentDateString(timeZone, pattern);
    }

    public static String currentDateString(String timeZone, String pattern) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        dateFormat.setTimeZone(TimeZone.getTimeZone(timeZone));
        return dateFormat.format(new Date());
    }

    /**
     * 生成size数量的随机时间，位于[start,end)范围内 时间倒序排列
     *
     * @param start 开始时间
     * @param end   结束时间
     * @param size  生成时间个数
     * @return List<Date>
     * @throws Exception
     */
    public static List<Date> randomDate(String start, String end, int size) throws Exception {
        return randomDate(parse(start), parse(end), size);
    }

    /**
     * 生成size数量的随机时间，位于[start,end)范围内 时间倒序排列
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param size      生成时间个数
     * @return List<Date>
     * @throws Exception
     */
    public static List<Date> randomDate(Date startTime, Date endTime, int size) throws Exception {
        List<Date> dates = ThreadLocalRandom.current().longs(size, startTime.getTime(), endTime.getTime()).mapToObj(t -> new Date(t)).collect(Collectors.toList());
        dates.sort((t1, t2) -> {
            return t1.compareTo(t2);
        });
        return dates;
    }
}
